/*
 * GraphState2.h
 *
 *  Created on: Jun 28, 2011
 *      Author: pickrell
 */

#ifndef TREESTATE_H_
#define TREESTATE_H_

#include "Settings.hpp"
#include "PopTree.h"
#include "Alignment.h"


class TreeState{
public:
	TreeState();
	TreeState(Alignment*, PhyloPop_params*);

	PhyloPop_params* params; //paramters for run
	PopTree* tree;
	PopTree* tree_bk;
	PopTree* tree_bk2;
	PopTree* tree_bk3;

	void set_to_newick(string);
	void print();

	Alignment* aln; //pointer to the data
	vector<string> allhapnames; //names of populations, will be added one at a time after the first 3
	map<string, int> hapname2index; //go from the population name to the index in the above vector
	int current_nhap; //current total number of populations
	double current_llik;

	void add_pop();
	int local_hillclimb(int);
	int local_hillclimb_root();
	int many_local_hillclimb();
	void iterate_hillclimb();

	// optimize the tip labels
	void optimize_single_tip(Graph::vertex_descriptor, double, vector<double> *,  vector<double>* , vector<double> *);
	void optimize_all_tips(double, vector<double> *, vector<double>* , vector<double> *);
	void iterate_optimize_all_tips(double, vector<double> *,  vector<double>* , vector<double> *);
	//copied from Tree
	void print_coales();
	void set_coaltimes();
	void set_labeled_coaltimes();
	vector<double> coaltimes;
	vector<double> coaltimes1, coaltimes2, coaltimes3;
	vector<pair<double, int> > coals12;

	int n1, n2;
	void flip_labels(vector<Graph::vertex_descriptor>);
	vector<Graph::vertex_descriptor> move_label_subset(vector<Graph::vertex_descriptor>, int);

	void init_tip_labels(double, gsl_rng *);
	void assign_labels(Graph::vertex_descriptor, int);
	void assign_labels(Graph::vertex_descriptor, gsl_rng*, double);
	void set_heights();
	double llk(vector<double>*, vector<double>*);
	double llk(int, double, double, vector<double>, vector<double>*, vector<double>*);
	double llk12(vector<double>*, vector<double>*, vector<double>*);
	double structured_llk(double, double, vector<double> *,  vector<double> *, vector<double> *, vector<double>*, vector<double>*);
	double structured_llk_nof(double, vector<double> *,  vector<double> *, vector<double> *, vector<double>*, vector<double>*);
	double structured_llk_no3(double, vector<double> *, vector<double> *, vector<double> *);
	double structured_llk_binom(double);
	double getp();
	void set_known(int);
	void set_popid(Graph::vertex_descriptor, int);

	void set_UPGMA();

	void print_coals12();

};

extern bool comp_vertex(pair<double, int>, pair<double, int>);

#endif /* TREESTATE_H_ */
